namespace Bootsy.Voting

import Bootsy.Core
import Bootsy.PEG
import ConcurrentBoo.Executors		

class VotingBot(GrammarBasedBot):
	
	_executor as IExecutor
	
	def constructor():
	"""
	Sets up a QueuedExecutor to avoid explicit synchronization.
	"""
		self(QueuedExecutor())
	
	def constructor([required] executor as IExecutor):
		super(SetUpGrammar())
		_executor = executor
		
	private def SetUpGrammar():
		return ((literal("!voting")
					>> (literal("begin", BeginVoting)
						| literal("end", EndVoting)
						| literal("details", VotingDetails))
				| re(/^(\+|-)\d+/, ComputeVote))
				>> eof())
		
	class Vote:
		
		[getter(Value)]
		_value as int
		
		[getter(Sender)]
		_sender as IChatUser
		
		def constructor(value as int, sender as IChatUser):
			_value = value
			_sender = sender
			
	_votes = System.Collections.Generic.List[of Vote]()
		
	private def BeginVoting(_ as string, message as IChatMessage):
		
		_executor.Execute({ _votes.Clear() })
		
	private def EndVoting(_ as string, message as IChatMessage):
		_executor.Execute() do:			
			message.Chat.PostMessage("The votes are in and the final count is: ${CountVotes()}")
		
	private def ComputeVote(vote as string, message as IChatMessage):
		_executor.Execute() do:
			_votes.Add(Vote(int.Parse(vote), message.Sender))
			
	private def VotingDetails(_ as string, message as IChatMessage):
		
		_executor.Execute() do:
			if _votes.Count == 0:
				message.Chat.PostMessage("No votes received so far.")
				return
				
			details = "${vote.Sender.FullName}\t${vote.Value}" for vote in _votes
			message.Chat.PostMessage(join(details, "\n"))
		
	private def CountVotes():
		total = 0
		for vote in _votes:
			total += vote.Value
		return total
	
